/* 
 *  Copyright 2012 CodeMagi, Inc.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.codemagi.taglibs.input;

import com.codemagi.servlets.BaseServlet;
import com.codemagi.util.Utils;
import java.util.*;
import javax.servlet.http.*;
import javax.servlet.jsp.tagext.*;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;

/**
 *  This class is the base class for all input taglibs
 *
 *  @version 1.0
 *  @author August Detlefsen for CodeMagi, Inc.
 */
public class Input extends TagSupport {

    static Logger log = Logger.getLogger("com.codemagi.taglibs.input.Input");

    protected String name;	          	 // name of the text field
    protected String id;                         // javascript id of the input
    protected String dVal        = "";           // default value if none is found
    protected String markupClass = "";           // CSS class for the input
    protected String onChange    = "";           // JavaScript OnChange attribute
    protected boolean override   = false;        // if true, overrides request and uses default 
    protected boolean disabled   = false;        // if true, disables changes to this form field
    protected Map attributes = new HashMap();		// attributes of the <input> element
    protected boolean showError  = false;        //if true, taglib will create HTML to display an error message below the input tag

    public void setName(String x) {
	name = x;
    }

    public void setId(String x) {
	id = x;
    }

    public void setMarkupClass(String newValue) {
	markupClass = newValue;
    }

    public void setOnChange(String x) {
	onChange = x;
    }

    /**
     * Returns the ID set by setId(), or the tag name if the ID is null
     */
    protected String getMarkupId() {
	return Utils.isEmpty(id) ? name : id ;
    }

    public void setAttributes(Map x) {
	if (x != null) attributes = x;
    }

    /** 
     * Sets an attribute in the attributes map. Note that the contract for the attributes Map is that it only contains Strings.
     */
    public void appendAttribute(String key, String value) {

	appendAttribute(key, value, attributes);

	/*
	if (Utils.isEmpty(key) || Utils.isEmpty(value)) return;

	attributes = (HashMap)((HashMap)attributes).clone();

	String actualKey   = Util.getKeyIgnoreCase(key, attributes);
	String actualValue = (String)attributes.get(actualKey);

	if ( Utils.isEmpty(actualValue)) {
	    actualValue = value;
	} else {
	    actualValue = actualValue + value;
	}

	attributes.put(actualKey, actualValue);
	*/
    }

    /** 
     * Sets an attribute in the attributes map. Note that the contract for the attributes Map is that it only contains Strings.
     */
    public static void appendAttribute(String key, String value, Map attributes) {
	if (Utils.isEmpty(key) || Utils.isEmpty(value)) return;

	attributes = (HashMap)((HashMap)attributes).clone();

	String actualKey   = Util.getKeyIgnoreCase(key, attributes);
	String actualValue = (String)attributes.get(actualKey);

	if ( Utils.isEmpty(actualValue)) {
	    actualValue = value;
	} else {
	    actualValue = actualValue + value;
	}

	attributes.put(actualKey, actualValue);
    }

    public void setDefault(Object x) {
	log.debug(name + " setDefault( (Object)" + x + " )");
	if (x == null) {
	    dVal = "";
	} else if (x instanceof String) {
	    setDefault( (String)x );

	} else if (x instanceof Integer) {
	    setDefault( (Integer)x );

	} else if (x instanceof Float) {
	    setDefault( (Float)x );

	} else if (x instanceof Boolean) {
	    setDefault( (Boolean)x );

	} else if (x instanceof Collection) {
	    setDefault( (Collection)x );

	} else {
	    setDefault( x.toString() );

	}
    }

    protected void setDefault(Boolean x) {
        log.debug(name + " setDefault( (Boolean)" + x + " )");
        if (x != null) dVal = x.toString();
    }

    protected void setDefault(Float x) {
	log.debug(name + " setDefault( (Float)" + x + " )");
	if (x == null) {
	    setDefault("");
        } else {
            setDefault(x.toString());
	}
    }

    protected void setDefault(Integer x) {
	log.debug(name + " setDefault( (Integer)" + x + " )");
	if (x == null) {
	    setDefault("");
	} else {
	    setDefault(x.toString());
	}	    
    }

    protected void setDefault(String x) {
	log.debug(name + " setDefault( (String)" + x + " )");
	dVal = x;
    }

    protected void setDefault(Collection x) {
	log.debug(name + " setDefault( (Collection)" + x + " )");
	if (x == null) {
            setDefault("");
        } else {
	    setDefault(x.toString());
	}
    }

    public void setOverride(boolean x) {
        override = x;
    }

    public void setOverride(Boolean x) {
	if (x == null) {
	    override = false;
	} else {
	    override = x.booleanValue();
	}
    }

    public void setDisabled(boolean x) {
        disabled = x;
    }

    public void setDisabled(Boolean x) {
	if (x == null) {
	    disabled = false;
	} else {
	    disabled = x.booleanValue();
	}
    }

    public void setShowerror(boolean x) {
        showError = x;
    }

    /**
     * Returns a parameter from the request
     */
    protected static String getParameter(String name, HttpServletRequest request) {

	if (ServletFileUpload.isMultipartContent(request)) {
	    //see if we have already parsed the params
	    Map requestParams = (Map)request.getAttribute("requestParams");

	    if (requestParams == null) {
		//parse param out of the multipart
		try {
		    requestParams = BaseServlet.parseCommonsMultipart(request);

		    //stick into request attributes so we don't have to re-parse for subsequent tags
		    request.setAttribute("requestParams", requestParams);

		} catch (Exception ae) {
		    //		    log.debug("Error parsing multipart - This should never happen", ae);
		}

	    }

	    Object output = requestParams.get(name);
	    if (output instanceof String) {
		return (String)output;

	    } else if (output instanceof List) {
		return ((List<String>)output).get(0);

	    }

	} else {
	    return request.getParameter(name);

	}	

	return null;
    }

    /**
     * Returns an array of parameter values from the request
     */
    protected static String[] getParameterValues(String name, HttpServletRequest request) {

	if (ServletFileUpload.isMultipartContent(request)) {
	    //see if we have already parsed the params
	    Map requestParams = (Map)request.getAttribute("requestParams");

	    if (requestParams == null) {
		//parse param out of the multipart
		try {
		    requestParams = BaseServlet.parseCommonsMultipart(request);

		    //stick into request attributes so we don't have to re-parse for subsequent tags
		    request.setAttribute("requestParams", requestParams);

		} catch (Exception ae) {
		    log.debug("Error parsing multipart - This should never happen", ae);
		}

	    }

	    Object param = requestParams.get(name);
	    if (param instanceof String) {
		String[] output = { (String)param };
		return output;

	    } else if (param instanceof List) {
		String[] type = {""};
		return ((List<String>)param).toArray(type);

	    }

	} else {
	    return request.getParameterValues(name);

	}	

	return null;
    }

}
